package com.arpa.wms.mapper;

import com.arpa.wms.domain.dto.DeliveryDTO;
import com.arpa.wms.domain.dto.DeliveryDistributionDTO;
import com.arpa.wms.domain.dto.RecheckOperationDto;
import com.arpa.wms.domain.dto.WaveQueryGoodsDTO;
import com.arpa.wms.domain.entity.Delivery;
import com.arpa.wms.domain.entity.DeliveryDistribution;
import com.arpa.wms.domain.entity.Picking;
import com.arpa.wms.domain.vo.DeliveryItemImportVO;
import com.arpa.wms.domain.vo.DeliveryVO;
import com.arpa.wms.domain.vo.WaveQueryGoodsVO;
import com.baomidou.mybatisplus.annotation.SqlParser;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * <p>
 * 出货单 Mapper 接口
 * </p>
 *
 * @author LEO
 * @since 2020-08-07
 */
public interface DeliveryMapper extends BaseMapper<Delivery> {

    /**
     * 查询列表
     * @param deliveryDTO
     * @return
     */
    List<DeliveryVO> queryList(DeliveryDTO deliveryDTO);

    /**
     * 查询合计,包含总数
     * @param sql
     * @return
     */
    DeliveryVO queryListSum(@Param("sql") String sql);

    /**
     * 查询合计,包含总数
     * @param deliveryDTO
     * @return
     */
    DeliveryVO queryListTotal(DeliveryDTO deliveryDTO);

    /**
     * 更新发货数量
     * @param deliveryDTO
     * @return
     */
    int updateSendNum(DeliveryDTO deliveryDTO);



    /**
     * 关联查询明细表，用于判断明细表中是否包含某些商品
     * @param deliveryDTO
     * @return
     */
    List<DeliveryVO> queryListJoinItem(DeliveryDTO deliveryDTO);

    /**
     * 查询合计,包含总数， 用于关联查询明细表，用于判断明细表中是否包含某些商品
     * @param deliveryDTO
     * @return
     */
    DeliveryVO queryListJoinItemSum(DeliveryDTO deliveryDTO);


    /**
     * 拣货确认时更新订单拣货数量
     * @param entity
     * @return
     */
    int updatePickingQuantity(Picking entity);

    /**
     * 查询可退货订单列表
     * @param deliveryDTO
     * @return
     */
    List<DeliveryVO> queryCanRefundList(DeliveryDTO deliveryDTO);

    /**
     * 调整发货单已分配数量，正数为加，负数为减
     * @param deliveryDTO
     * @return
     */
    int adjustDistributionNum(DeliveryDTO deliveryDTO);

    /**
     * @description
     * 根据分配单的拣货数量更新主表的拣货数量
     * @author xuyang
     * @date 2020/10/26 11:02
     * @param code:
     **/
    int updatePickNumByDistributionData(@Param("code") String code,@Param("groupCode") String groupCode);

    /**
     * 更新退货数量
     * @param deliveryCode
     */
    int updateRefundQuantity(@Param("code") String deliveryCode,@Param("groupCode") String groupCode);

    /**
     * 出库复核时更新发货单分配数量，如缺货登记后需要调整实际分配数量
     * @param deliveryCode
     * @return
     */
    int updateDistributionQuantityForOutboundRecheck(@Param("code") String deliveryCode, @Param("groupCode")String groupCode);

    /**
     * 与queryList方法一致，但没有分页限制
     * @param deliveryDTO
     * @return
     */
    List<DeliveryVO> queryAllList(DeliveryDTO deliveryDTO);

    long queryNotAllocatedCount(DeliveryDTO deliveryDTO);

    /**
     * 更新发货单状态为生成波次中
     * @param deliveryDTO 更新条件
     */
    void updateDeliveryWaveStatus(DeliveryDTO deliveryDTO);

    /**
     * 根据波次号，更新发货单拣货数量
     * @param wavePickingCode
     * @return
     */
    int updatePickingQuantityByWavePickingCode(@Param("wavePickingCode") String wavePickingCode, @Param("groupCode")String groupCode);

    /**
     * 出库确认，释放临时库存
     * @param deliveryCode
     * @return
     */
    int releaseTempInv(@Param("deliveryCode") String deliveryCode, @Param("groupCode")String groupCode);

    /**
     * 出库确认获取波次内所有订单状态
     * @author liuxr
     * @date 2021/4/23 17:33
     * @param wavePickingCode  波次号
     * @return java.util.List<java.lang.String>
     */
    Set<String> findDeliveryStatusForConfirmDelivery(@Param("wavePickingCode")String wavePickingCode, @Param("groupCode")String groupCode);


    /**
     * 出库确认获取波次内所有复核条件得订单
     * @author liuxr
     * @date 2021/4/23 17:34
     * @param wavePickingCode 波次号
     * @return java.util.List<com.arpa.wms.domain.entity.Delivery>
     */
    List<Delivery> findDeliveryForConfirmDelivery(@Param("wavePickingCode")String wavePickingCode, @Param("groupCode")String groupCode);

    /**
     * 更新订单面单信息
     * @param code 发货单标识
     * @param wayBillCode 面单号
     * @param signature 验签
     * @param url 模板url
     */
    void updateWayBillCode(@Param("code") String code,
                           @Param("wayBillCode") String wayBillCode,
                           @Param("signature") String signature,
                           @Param("url") String url,
                           @Param("printData")String printData,
                           @Param("routeCode")String routeCode,
                            @Param("groupCode") String groupCode);

    void updateRemarks(@Param("deliveryCodes") List<String> deliveryCodes, @Param("remarks") String remarks,@Param("groupCode") String groupCode);

    /**
     * 根据订单号统计承运商数量
     *
     * @param codes 订单号
     * @return
     */
    int countLogistics(@Param("codes") List<String> codes,@Param("groupCode")String groupCode);
    /**
     * 根据订单号统计货主数量
     *
     * @param codes 订单号
     * @return
     */
    int countShipment(@Param("codes") List<String> codes,@Param("groupCode")String groupCode);

    /**
     * 发货单波次分组信息
     *  [shipmentCode:,logisticsCode:,count:]
     * @param codes 订单号
     * @return
     */
    List<Map<String,Object>> queryWaveGroupInfo(@Param("codes") List<String> codes,@Param("groupCode")String groupCode);

    /**
     * 更新生成波次状态
     * @param codes
     * @param temporaryCode
     */
    void updateWaveStatus(@Param("codes") List<String> codes,@Param("temporaryCode")  String temporaryCode,@Param("groupCode")String groupCode);

    /**
     * 根据条件获取未取消的发货单信息
     * @param shipmentCode 入驻商
     * @param logisticsCode 承运商
     * @param temporaryCode 临时标识
     * @return
     */
    Delivery getFirstDeliveryInfo(@Param("shipmentCode") String shipmentCode,
                                  @Param("logisticsCode") String logisticsCode,
                                  @Param("temporaryCode") String temporaryCode,
                                  @Param("prepackagedCode") String prepackagedCode);





    BigDecimal getDistributionNumSum(@Param("shipmentCode")  String shipmentCode,
                                     @Param("logisticsCode")  String logisticsCode,
                                     @Param("temporaryCode")  String temporaryCode,
                                     @Param("pageNum")  Integer pageNum,
                                     @Param("pageSize")  Integer pageSize,
                                     @Param("prepackagedCode") String prepackagedCode);

    List<Map<String, Object>> queryDeliveryDistributionWaveGroupInfo(@Param("shipmentCode") String shipmentCode,
                                                                     @Param("groupCode")String groupCode,
                                                                     @Param("logisticsCode") String logisticsCode,
                                                                     @Param("temporaryCode") String temporaryCode,
                                                                     @Param("pageNum") Integer pageNum,
                                                                     @Param("pageSize") Integer pageSize,
                                                                     @Param("prepackagedCode") String prepackagedCode);

    DeliveryDistribution getFirstDistributionInfo(@Param("inventoryCode") String inventoryCode,@Param("deliveryCodes") List<String> deliveryCodes);

    /**
     * 大数据量直接根据条件更新会导致更新慢，因为update语句也是先查找再更新，查找时会缓存所有字段
     * 故先查找符合条件的id列表，然后根据id列表进行更新
     * @see #getDeliveryStatusIdList
     * @see #updateDeliveryStatus2
     *
     * @param shipmentCode
     * @param logisticsCode
     * @param wavePickingCode
     * @param temporaryCode
     * @param pageNum
     * @param pageSize
     * @param prepackagedCode
     */
    @Deprecated
    void updateDeliveryStatus(@Param("shipmentCode")  String shipmentCode,
                                  @Param("logisticsCode")  String logisticsCode,
                                  @Param("wavePickingCode")  String wavePickingCode,
                                  @Param("temporaryCode")  String temporaryCode,
                                  @Param("pageNum")  Integer pageNum,
                                  @Param("pageSize")  Integer pageSize,
                                  @Param("prepackagedCode") String prepackagedCode);

    List<Long> getDeliveryStatusIdList(@Param("shipmentCode")  String shipmentCode,
                                  @Param("logisticsCode")  String logisticsCode,
                                  @Param("wavePickingCode")  String wavePickingCode,
                                  @Param("temporaryCode")  String temporaryCode,
                                  @Param("pageNum")  Integer pageNum,
                                  @Param("pageSize")  Integer pageSize,
                                  @Param("prepackagedCode") String prepackagedCode);

    void updateDeliveryStatus2(@Param("wavePickingCode")  String wavePickingCode,@Param("idList") List<Long> idList,@Param("groupCode")String groupCode);


    void updateDeliveryItem(@Param("wavePickingCode") String wavePickingCode,@Param("deliveryCodes") List<String> deliveryCodes,@Param("groupCode")String groupCode);


    void updateDeliveryDistribution(@Param("wavePickingCode") String wavePickingCode,@Param("deliveryCodes") List<String> deliveryCodes,@Param("groupCode")String groupCode);


    /**
     * 根据波次
     * @author liuxr
     * @date 2021/4/29 11:39
     * @param wavePickingCode
     * @return java.util.List<java.lang.String>
     */
    List<String> getDeliveryCodes(@Param("wavePickingCode") String wavePickingCode,@Param("groupCode")String groupCode);

    /**
     * 订单处理页面-商品查询总数
     * @param waveQueryGoodsDTO
     * @return
     */
    WaveQueryGoodsVO waveQueryGoodsSum(WaveQueryGoodsDTO waveQueryGoodsDTO);

    /**
     * 订单处理页面-商品查询结果
     * @param waveQueryGoodsDTO
     * @return
     */
    List<WaveQueryGoodsVO> waveQueryGoods(WaveQueryGoodsDTO waveQueryGoodsDTO);

    /**
     * 订单处理页面-爆品商品查询总数
     * @param waveQueryGoodsDTO
     * @return
     */
    WaveQueryGoodsVO waveQueryHotGoodsSum(WaveQueryGoodsDTO waveQueryGoodsDTO);

    /**
     * 订单处理页面-爆品商品查询结果
     * @param waveQueryGoodsDTO
     * @return
     */
    List<WaveQueryGoodsVO> waveQueryHotGoods(WaveQueryGoodsDTO waveQueryGoodsDTO);

    /**
     * 普通复核更新复核数量
     * @author liuxr
     * @date 2021/4/12 18:45
     * @param code 订单明细code
     * @param reviewCount 复核数量
     * @return int 更新条数
     */
    int generalReviewUpdateInfo(@Param("code") String code, @Param("reviewCount") BigDecimal reviewCount,@Param("groupCode")String groupCode);

    /**
     * 当订单不需要复核操作时，需要在生成出库单时更新订单状态
     * @param wavePickingCode
     * @return
     */
    int updateStatusWithoutRecheck(@Param("wavePickingCode") String wavePickingCode,@Param("groupCode")String groupCode);

    /**
     * 订单需要复核操作时，需要再生成出库单时更新订单状态
     * @param wavePickingCode
     * @return
     */
    int updateStatusWithRecheck(@Param("wavePickingCode")String wavePickingCode,@Param("groupCode")String groupCode);


    /**
     * 更新复核数量
     * @param deliveryCode
     */
    int updateRecheckQuantity(@Param("code") String deliveryCode,@Param("groupCode")String groupCode);

    List<String> getDeliveryCodesByShipmentCodeAndLogisticsCodeAndTemporaryCode(
            @Param("shipmentCode") String shipmentCode,
            @Param("logisticsCode") String logisticsCode,
            @Param("temporaryCode") String temporaryCode,
            @Param("prepackagedCode") String prepackagedCode,
            @Param("groupCode")String groupCode);

    void waybillDiscard(@Param("code") String deliveryCode,@Param("groupCode")String groupCode);

    /**
     * 根据商品条码查询列表
     * @param deliveryDTO
     * @return
     */
    List<DeliveryVO> queryListByGoodsBarCode(DeliveryDTO deliveryDTO);

    /**
     * @param itemCode :
     * @param status   :
     * @description 根据拣货量与复核量+退减量的比较，尝试更新明细的状态
     * @author xuyang
     * @date 2020/10/29 8:55
     **/
    int updateStatusIfFinishRecheck(@Param("code") String itemCode, @Param("status") String status,@Param("groupCode")String groupCode);

    /**
     * 根据波次号统计订单计划总量
     *
     * @param wavePickingCode 波次号
     * @return java.math.BigDecimal 订单计划总量
     * @author liuxr
     * @date 2021/5/15 9:56
     */
    BigDecimal getTotalNumByWavePickingCode(@Param("wavePickingCode")String wavePickingCode,@Param("groupCode")String groupCode);
    /**
     * 根据波次号统计订单商品种类总量
     *
     * @param wavePickingCode 波次号
     * @return java.math.BigDecimal  订单商品种类总量
     * @author liuxr
     * @date 2021/5/15 9:56
     */
     BigDecimal  getGoodsTotalNumByWavePickingCode(@Param("wavePickingCode")String wavePickingCode,@Param("groupCode")String groupCode);

    /**
     * 根据波次号更新发货明细的复核数量
     * @param wavePickingCode
     * @return
     */
    int updateRecheckQuantityByWavePickingCode(@Param("wavePickingCode")String wavePickingCode,@Param("groupCode")String groupCode);

    void updateRecheckQuantityAndStatus(@Param("codes") Set<String> deliveryCodes, @Param("status") String status,@Param("groupCode")String groupCode);

    void batchUpdatePrintCount(@Param("deliveryDTOS") List<DeliveryDTO> deliveryDTOS);
    void addPrintCount(@Param("code") String deliveryCode,@Param("groupCode")String groupCode);

    /**
     * 查询合计,异常订单总数
     * @param deliveryDTO
     * @return
     */
    DeliveryVO queryAbnormalListSum(DeliveryDTO deliveryDTO);

    /**
     * 查询异常单列表
     * @param deliveryDTO
     * @return
     */
    List<DeliveryVO> queryAbnormalList(DeliveryDTO deliveryDTO);




    /**
     * 波次拣货确认，不需要复核操作时，自动更新订单复核数量及状态
     * @param wavePickingCode
     * @param groupCode
     * @return
     */
    int autoUpdateStatusAndRecheckQuantity(@Param("wavePickingCode") String wavePickingCode,@Param("groupCode") String groupCode);

    /**
     * 爆品复核时，根据订单分配的复核数量，更新同波次下的订单明细及订单的复核数量
     * @param deliveryDistributionDTO
     * @return
     */
    int hotReviewUpdateRecheckQuantity(DeliveryDistributionDTO deliveryDistributionDTO);

    /**
     * 复核出库确认，自动更新订单复核数量及状态
     * @param deliveryDistributionDTO
     */
    int autoUpdateRecheckQuantityByCodes(DeliveryDistributionDTO deliveryDistributionDTO);
    /**
     * 波次拣货确认，不需要复核操作时，自动更新订单出库数量及状态
     *
     * @param deliveryCodes 订单号
     */
    void autoUpdateStatusAndSendQuantity(@Param("codes") Set<String> deliveryCodes,@Param("groupCode") String groupCode);

    /**
     * 波次拣货缺货登记，更新订单缺货数量
     *
     * @param deliveryCode             订单号
     * @author liuxr
     * @date 2021/6/5 17:05
     */
    void updateOutStockQuantity(@Param("deliveryCode") String deliveryCode,@Param("groupCode") String groupCode);

    /**
     * 波次拣货缺货登记，更新订单分配明细、订单明细缺货数量、拣货数量和状态
     *
     * @param refundQuantity           缺货数量
     * @param deliveryDistributionCode 分配明细标识
     * @param deliveryItemCode         订单明细标识
     * @author liuxr
     * @date 2021/6/5 17:05
     */
    void updateItemsOutStockQuantity(@Param("refundQuantity") BigDecimal refundQuantity,
                                     @Param("deliveryDistributionCode") String deliveryDistributionCode,
                                     @Param("deliveryItemCode") String deliveryItemCode
                                     );
    @SqlParser(filter = true)
    @Select("SELECT " +
            "count(a.code) visual " +
            "FROM wms_delivery a " +
            "WHERE a.status = #{status} AND a.is_deleted = 0 AND left(a.gmt_created, 10) =  left(#{time}, 10) AND a.group_code = #{groupCode}")
    String outboundQuantityTrend(@Param("time") String time,@Param("status") String status,@Param("groupCode") String groupCode);

    List<DeliveryVO> queryWaveList(DeliveryDTO deliveryDTO);

    DeliveryVO queryWaveListJoinItemSum(DeliveryDTO deliveryDTO);

    List<DeliveryVO> queryWaveListJoinItem(DeliveryDTO deliveryDTO);

    /**
     * 查询合计,待打包订单总数
     * @param deliveryDTO
     * @return
     */
    DeliveryVO queryWaitingPackingOrderListSum(DeliveryDTO deliveryDTO);

    /**
     * 查询待打包列表
     * @param deliveryDTO
     * @return
     */
    List<DeliveryVO> queryWaitingPackingOrderList(DeliveryDTO deliveryDTO);

    /**
     * 根据codes更新实体
     * @param dto
     * @return
     */
    int updateByCodes(DeliveryDTO dto);

    /**
     * 发货单打包任务分组信息
     *  [shipmentCode:,carrierCode:,carrierName:,count:,totalNum:]
     * @param codes 订单号
     * @return
     */
    List<Map<String,Object>> queryPackTaskGroupInfo(@Param("codes") List<String> codes,@Param("groupCode") String groupCode);

    /**
     * 根据订单号更新发货单的复核数量
     * @param code
     * @return
     */
    int updateRecheckQuantityByCode(@Param("code")String code, @Param("groupCode") String groupCode);

    /**
     * @description
     * 根据波次号，更新复合数量和状态
     * @author rfwang
     * @date 2021年7月16日
     * @param wavePickingCode:
     **/
    int updateRecheckQuantityAndStatsuByWavePickingCode(@Param("wavePickingCode") String wavePickingCode, @Param("groupCode") String groupCode);



    /**
     * 获取生成波次的订单号
     * @author liuxr
     * @date 2021/12/9 9:08
     * @param shipmentCode
     * @param logisticsCode
     * @param temporaryCode
     * @param prepackagedCode
     * @return java.util.List<com.arpa.wms.domain.entity.Delivery>
     */
    List<String> getGenWaveDeliveryCodes(@Param("shipmentCode") String shipmentCode,
                                         @Param("logisticsCode") String logisticsCode,
                                         @Param("temporaryCode") String temporaryCode,
                                         @Param("prepackagedCode") String prepackagedCode,
                                         @Param("pageNum")  Integer pageNum,
                                         @Param("pageSize")  Integer pageSize);


    /**
     * 根据要生成波次的订单号获取 订单分配数量统计
     * @author liuxr
     * @date 2021/12/9 10:13
     * @param codes
     * @return java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
     */
    List<Map<String, Object>> getDeliveryDistributionWaveGroupInfo(@Param("codes") List<String> codes,@Param("groupCode") String groupCode);

    /**
     * 获取生成波次的订单商品种类数量
     * @author liuxr
     * @date 2021/12/9 10:21
     * @param codes
     * @return int
     */
    int getGoodsSortQuantity(@Param("codes") List<String> codes,@Param("groupCode") String groupCode);

    /**
     * 更新生成波次的订单波次号和待拣货状态
     * @author liuxr
     * @date 2021/12/9 13:13
     * @param wavePickingCode
     * @param codes
     */
    void updateGenWaveDeliveryWavePickingCode(@Param("wavePickingCode") String wavePickingCode, @Param("codes") List<String> codes,@Param("groupCode") String groupCode);


    /**
     * 获取生成波次订单商品分组统计数量
     * @author liuxr
     * @date 2021/12/9 14:08
     * @param codes
     * @return java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
     */
    List<Map<String, Object>> getDeliveryItemGoodsSortQuantity( @Param("codes") List<String> codes,@Param("groupCode") String groupCode);

    /**
     * 批量更新复核数量
     * @author rfwang
     * @date 2021/12/20 20:12
     * @param recheckOperationDtoList
     * @return
     */
    void batchRecheck(List<RecheckOperationDto> recheckOperationDtoList);

    /**
     * 波次下的订单数量
     * @return
     */
    Integer cancelWaveTipsPrompt(@Param("wavePickingCode") String wavePickingCode,@Param("groupCode") String groupCode);


    void cancelWaveTips(String wavePickingCode);

    List<DeliveryVO> importDelivery(DeliveryDTO deliveryDTO);

    /**
     * 查询导出数据合计,包含总数
     * @param deliveryDTO
     * @return
     */
    DeliveryVO importDeliveryTotal(DeliveryDTO deliveryDTO);

    List<DeliveryItemImportVO> importItemDelivery(DeliveryDTO deliveryDTO);

    /**
     * 根据波次号更新面单的打印次数
     * @param wavePickingCode
     * @return
     */
    void updatePrintCountByWavePickingCode(@Param("wavePickingCode") String wavePickingCode,@Param("groupCode") String groupCode);

    /**
     * 订单处理查询合计,包含总数
     * @param deliveryDTO
     * @return
     */
    DeliveryVO queryWaveListTotal(DeliveryDTO deliveryDTO);

    /**
     * 查询列表
     * @param deliveryDTO
     * @return
     */
    List<DeliveryVO> queryBdList(DeliveryDTO deliveryDTO);

    /**
     * 获取订单来源平台信息
     * @param
     * @return
     */
    List<DeliveryVO> chooseSourcePlatformList(String groupCode);
}
